/**
 * 
 */
package main;

import ihm.AfficherImage;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import defi5.Boulanger;
import defi5.Cycle;
import defi5.GrandsNombres;
import defi5.Indices;
import defi5.Point;

/**
 * @author Logan
 *
 */
public class MainDefi5 {
	
	public static Point transformePoint(int w, int h, Point p, int nbFois) {
		for(int i = 0; i<nbFois; i++) {
			p = Boulanger.boulanger(p.x, p.y, w, h);
		}

		return p;
	}


	public static void main(String [] args) throws IOException {

		// 498 600 taille de limage.
		
		long tempsDebut = System.currentTimeMillis();
		

		BufferedImage img = ImageIO.read(new File("image.png"));
		
		int w = img.getWidth();
		int h = img.getHeight();
		BufferedImage imgTmp = new BufferedImage(img.getWidth(),img.getHeight(),img.getType());
		BufferedImage img2 = new BufferedImage(img.getWidth(),img.getHeight(),img.getType());
		int rgbRef = imgTmp.getRGB(0, 0);



		//========================== CREATION DES CYCLES =================================
		List<Cycle> cycles = new ArrayList<Cycle> ();
		Indices ind = new Indices();
		int currentInd = 0;

		for (int i=0; i<w; ++i) {
			for (int j=0; j<h; ++j) {
				if(imgTmp.getRGB(i, j) == rgbRef) {
					Cycle c = new Cycle();
					Point p1 = new Point(i,j);
					currentInd = 1;
					c.getPoints().add(p1);
					
					imgTmp.setRGB(p1.x, p1.y, 20);
					Point p2 = Boulanger.boulanger(p1.x, p1.y, w, h);
					if(ind.contient(p2)) {
						c.setNbIterations(currentInd);
					}
					
					
					imgTmp.setRGB(p2.x, p2.y, 20);
					
					if(!p1.equals(p2)) {
						c.getPoints().add(p2);
					}
					
					while(!p1.equals(p2)) {
						p2 = Boulanger.boulanger(p2.x, p2.y, w, h);
						if(!p1.equals(p2)) {
							c.getPoints().add(p2);
						}
						currentInd++;
						imgTmp.setRGB(p2.x, p2.y, 20);
						if(ind.contient(p2)) {
							c.setNbIterations(currentInd);
						}
					}
					cycles.add(c);
				}
			}
		}
		

		System.out.println("==================== CYCLES ====================");
		for(Cycle currentC : cycles) {
			System.out.println(currentC.toString() + " - Reste a faire : " + currentC.getNbAFaire());
		}


		List<BigInteger> cyclesBI = new ArrayList<BigInteger>();
		for(Cycle bi : cycles) {
			BigInteger currentBi = new BigInteger(Integer.valueOf(bi.getPoints().size()).toString());
			cyclesBI.add(currentBi);
		}

		System.out.println("\n Temps de retour : " + GrandsNombres.ppcmMultiple(cyclesBI));
		
		
		// =========================================== DEBROUILLAGE DE LIMAGE ============================================
		for(Cycle currentC : cycles) {
			Point premierPoint = transformePoint(w, h, currentC.getPoints().get(0), currentC.getNbAFaire());
			img2.setRGB(premierPoint.x,premierPoint.y,img.getRGB(currentC.getPoints().get(0).x,currentC.getPoints().get(0).y));
			for(int i = 1 ; i<currentC.getPoints().size() -1 ; i++) {
				premierPoint = transformePoint(w, h, premierPoint, 1);
				img2.setRGB(premierPoint.x,premierPoint.y,img.getRGB(currentC.getPoints().get(i).x,currentC.getPoints().get(i).y));
			}
		}
		
		
		

		ImageIO.write(img2,"png",new File("out.png"));
		new AfficherImage("out.png", w, h);
		System.out.println("\n Fichier cree");
		
		long tempsFin = System.currentTimeMillis();
		Float seconds = (tempsFin - tempsDebut) / 1000F;
		
		System.out.println("\n Débrouillage effectué en : " + seconds.toString() + " secondes");

	}

}
